package com.example.framework509.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

@Component
public class SpringActuator {

    private static final String BASE_URL = "http://localhost:8080";

    public Map<String, Object> getDiskSpaceInfo() {
        JSONObject response = new RestTemplateUtil().getRequest(BASE_URL + "/actuator/health", null);
        JSONObject components = JSONObject.parseObject(response.getString("components"));
        JSONObject diskSpace = JSONObject.parseObject(components.getString("diskSpace"));
        JSONObject details = JSONObject.parseObject(diskSpace.getString("details"));
        Map<String, Object> map = new HashMap<>();
        map.put("total-C", details.getString("total"));
        map.put("free-C", details.getString("free"));
        return map;
    }

    public Map<String, Object> getTomcatInfo() {
        Map<String, Object> map = new HashMap<>();
        map.put("tomcat.sessions.created", getMetricsValue("tomcat.sessions.created"));
        map.put("tomcat.sessions.expired", getMetricsValue("tomcat.sessions.expired"));
        map.put("tomcat.sessions.active.current", getMetricsValue("tomcat.sessions.active.current"));
        map.put("tomcat.sessions.active.max", getMetricsValue("tomcat.sessions.active.max"));
        map.put("tomcat.sessions.rejected", getMetricsValue("tomcat.sessions.rejected"));
        map.put("tomcat.global.sent", "can't get");
        map.put("tomcat.global.request.max", "can't get");
        map.put("tomcat.global.request.count", "can't get");
        map.put("tomcat.global.request.totalTime", "can't get");
        map.put("tomcat.threads.current", "can't get");
        map.put("tomcat.threads.config.max", "can't get");
        return map;
    }

    public Map<String, Object> getServerInfo() {
        Map<String, Object> map = new HashMap<>();
        map.put("system.cpu.count", getMetricsValue("system.cpu.count"));
        map.put("system.cpu.usage", getMetricsValue("system.cpu.usage"));
        map.put("process.start.time", getMetricsValue("process.start.time"));
        map.put("process.uptime", getMetricsValue("process.uptime"));
        map.put("process.cpu.usage", getMetricsValue("process.cpu.usage"));
        return map;
    }

    public Map<String, Object>
    getJVMInfo() {
        Map<String, Object> map = new HashMap<>();
        map.put("jvm.memory.max", getMetricsValue("jvm.memory.max"));
        map.put("jvm.memory.committed", getMetricsValue("jvm.memory.committed"));
        map.put("jvm.memory.used", getMetricsValue("jvm.memory.used"));
        map.put("jvm.buffer.memory.used", getMetricsValue("jvm.buffer.memory.used"));
        map.put("jvm.buffer.count", getMetricsValue("jvm.buffer.count"));
        map.put("jvm.threads.daemon", getMetricsValue("jvm.threads.daemon"));
        map.put("jvm.threads.live", getMetricsValue("jvm.threads.live"));
        map.put("jvm.threads.peak", getMetricsValue("jvm.threads.peak"));
        map.put("jvm.classes.loaded", getMetricsValue("jvm.classes.loaded"));
        map.put("jvm.classes.unloaded", getMetricsValue("jvm.classes.unloaded"));
        map.put("jvm.gc.memory.allocated", getMetricsValue("jvm.gc.memory.allocated"));
        map.put("jvm.gc.memory.promoted", getMetricsValue("jvm.gc.memory.promoted"));
        map.put("jvm.gc.max.data.size", getMetricsValue("jvm.gc.max.data.size"));
        map.put("jvm.gc.live.data.size", getMetricsValue("jvm.gc.live.data.size"));
        map.put("jvm.gc.pause.count", getMetricsValue("jvm.gc.pause.count"));
        return map;
    }


    public String getMetricsValue(String indexName) {
        try {
            InetAddress address = InetAddress.getLocalHost();
            JSONObject response = new RestTemplateUtil().getRequest(BASE_URL + "/actuator/metrics/" + indexName, null);
            Object measurements = response.get("measurements");
            JSONArray jsonArray = JSONArray.parseArray(measurements.toString());
            JSONObject jsonObject = JSONObject.parseObject(jsonArray.get(0).toString());
            return jsonObject.get("value").toString();
        } catch (Exception exception) {
            return "error";
        }
    }
}
